package zsxking.batchfilerenamer;

import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.TableColumnModel;
import net.miginfocom.swing.MigLayout;

/**
 * GUI for BatchFileRenamer.
 * @author Shaoxuan
 *
 */
public class BatchFileRenamerGui extends JPanel {

  /** Support Serialization.*/
  private static final long serialVersionUID = 6141138601051629741L;
  
  private FileTableModel targetFileModel = new FileTableModel();
  private FileTableModel sourceFileModel = new FileTableModel();

  protected static final String LAYOUT_MODE = //"debug";
                                              "";
  
  private BatchFileRenamer fileRenamer;
  
  
  /**
   * Create the GUI and show it.  For thread safety,
   * this method should be invoked from the
   * event-dispatching thread.
   */
  public BatchFileRenamerGui() {
    super();
    setLayout(new MigLayout(LAYOUT_MODE, 
        "rel[grow,fill]rel[grow,fill]rel", 
        "rel[]rel[grow,fill]rel[]rel[]rel"));
    
    fileRenamer = new BatchFileRenamer();

    final StatusPanel statusBar = new StatusPanel();
    
    // List of target files.
    final JTable targetFileTable = new JTable(targetFileModel);
    TableColumnModel targetColumnModel = targetFileTable.getColumnModel();
    targetColumnModel.getColumn(0).setPreferredWidth(20);
    targetColumnModel.getColumn(1).setPreferredWidth(340);
    targetColumnModel.getColumn(2).setPreferredWidth(40);
    //targetFileList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
    final JScrollPane targetListScroller = new JScrollPane(targetFileTable);
    targetListScroller.setPreferredSize(new Dimension(400, 500));
    
    // button to add target file.
    final JFileChooser targetFileChooser = new JFileChooser();
    targetFileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
    targetFileChooser.setMultiSelectionEnabled(true);
    JButton targetFileChooserButton = new JButton("Add");
    targetFileChooserButton.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        int returnVal = targetFileChooser.showOpenDialog(BatchFileRenamerGui.this);
        if (returnVal == JFileChooser.APPROVE_OPTION) {
          File[] files = targetFileChooser.getSelectedFiles();
          targetFileModel.getFiles().addAll(Arrays.asList(files));
          targetFileTable.updateUI();
        }
      }
    });
    
    // button to remove target file.
    JButton targetFileRemoveButton = new JButton("Remove");
    targetFileRemoveButton.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        int removeCount = targetFileModel.removeData(targetFileTable.getSelectedRows()).size();
        statusBar.setMessage("" + removeCount + " files removed.");
        targetFileTable.updateUI();
        repaint();
      }
    });

    // List of source files.
    final JTable sourceFileTable = new JTable(sourceFileModel);
    JScrollPane sourceListScroller = new JScrollPane(sourceFileTable);
    sourceListScroller.setPreferredSize(new Dimension(400, 500));
    TableColumnModel sourceColumnModel = sourceFileTable.getColumnModel();
    sourceColumnModel.getColumn(0).setPreferredWidth(20);
    sourceColumnModel.getColumn(1).setPreferredWidth(340);
    sourceColumnModel.getColumn(2).setPreferredWidth(40);
    
    // button to add source file.
    final JFileChooser sourceFileChooser = new JFileChooser();
    sourceFileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
    sourceFileChooser.setMultiSelectionEnabled(true);
    JButton sourceFileChooserButton = new JButton("Add");
    sourceFileChooserButton.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        int returnVal = sourceFileChooser.showOpenDialog(BatchFileRenamerGui.this);
        if (returnVal == JFileChooser.APPROVE_OPTION) {
          File[] files = sourceFileChooser.getSelectedFiles();
          sourceFileModel.getFiles().addAll(Arrays.asList(files));
          sourceFileTable.updateUI();
          //repaint();
        }
      }
    });

    // button to remove source file.
    JButton sourceFileRemoveButton = new JButton("Remove");
    sourceFileRemoveButton.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        //System.out.println("Removing file from source list.");
        int removeCount = sourceFileModel.removeData(sourceFileTable.getSelectedRows()).size();
        statusBar.setMessage("" + removeCount + " files removed.");
        sourceFileTable.updateUI();
        repaint();
      }
    });

    //Submit button.
    JButton sortButton = new JButton("Sort by Name");
    sortButton.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        Collections.sort(sourceFileModel.getFiles());
        Collections.sort(targetFileModel.getFiles());
        targetFileTable.updateUI();
        sourceFileTable.updateUI();
      }
    });

    
    //Submit button.
    JButton submitButton = new JButton("Rename");
    submitButton.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        try {
          List<Boolean> results = 
            fileRenamer.rename(sourceFileModel.getFiles(), targetFileModel.getFiles());
          int succeedCount = 0;
          for (boolean result : results) {
            if (result) {
              succeedCount++;
            }
          }
          statusBar.setMessage(succeedCount + " files renamed. " + (sourceFileModel.getFiles().size() - succeedCount) + " failed.");
          sourceFileTable.updateUI();
        }
        catch (FileNameMatchException e1) {
          //e1.printStackTrace();
          statusBar.setMessage(e1.getMessage());
        }
      }
    });

    
    add(new JLabel("Source Files"), "split 3");
    add(sourceFileChooserButton, "right, width ::80");
    add(sourceFileRemoveButton, "right, width ::80");
    add(new JLabel("Target Files"), "split 3");
    add(targetFileChooserButton, "right, width ::80");
    add(targetFileRemoveButton, "right, width ::80, wrap");

    add(sourceListScroller);
    add(targetListScroller, "wrap");

    
    add(sortButton, "right, width ::120");
    add(submitButton, "left, width ::120, wrap");
    add(statusBar, "span 2, right");
  }
  
  /**
   * Run the tool.
   * @param args Command-line Arguments.
   */
  public static void main(String[] args) {
    JFrame frame = new JFrame();
    frame.setLayout(new MigLayout(LAYOUT_MODE, "rel[grow,fill]rel", "rel[grow,fill]rel"));
    frame.add(new BatchFileRenamerGui());
    //Close on clicking the close button.
    frame.addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
        System.exit(0);
        }
    });
    frame.setTitle("Batch File Renamer");
    frame.pack();
    frame.setMinimumSize(frame.getSize());
    //System.out.println(frame.getSize());
    frame.setVisible(true);
  }
}
